home *** CD-ROM | disk | FTP | other *** search
/ 10,000 Great Games / 10,000 Great Games.iso / Product / 66 / data1.cab / Source_Files / Src / Display.cpp < prev    next >
C/C++ Source or Header  |  2000-01-16  |  5KB  |  288 lines

  1. #include "stdafx.h"
  2.  
  3. cDisplayable::cDisplayable(cProperties *_orig)
  4. {    
  5.     if (_orig != 0)
  6.     {
  7.         orig = _orig;
  8.  
  9.         cmap = orig->cmap;
  10.         
  11.         circle_bounds = orig->circle;
  12.         line_bounds = orig->line;
  13.     }
  14.     else
  15.     {
  16.         orig = 0;
  17.  
  18.         cmap = 0;
  19.  
  20.         line_bounds = 0;
  21.         circle_bounds = 0;
  22.     }
  23.  
  24.     image = 0;
  25.     image_wait = 0;
  26.     
  27.     went_off_screen_horiz = FALSE;
  28.     force_dirty = TRUE;
  29.  
  30.     rotation_angle = 0;    
  31.     scale = 1;
  32. }
  33.  
  34. cDisplayable::~cDisplayable()
  35. {
  36.     make_dirty();
  37. }
  38.  
  39. void cDisplayable::update_image_variables()
  40. {
  41.     if (image == 0)
  42.     {
  43.         x1 = x, y1 = y;
  44.         x2 = x, y2 = y;
  45.     }
  46.     else
  47.     {
  48.         x1 = x - (int)(scale * image->origin_x);
  49.         y1 = y + (int)(scale * image->origin_y);
  50.         
  51.         x2 = x1 + (int)(scale * bitmap->w) - 1;
  52.         y2 = y1 - (int)(scale * bitmap->h) + 1;
  53.     }
  54. }
  55.  
  56. void cDisplayable::put_on_edge()
  57.     // Check sanity
  58.     
  59.     if (image == 0 || bitmap->w > surface->w - 2 * surface->edge)
  60.         return;
  61.     
  62.     // Check if object is not on screen anymore
  63.         
  64.     
  65.     if (x1 < surface->edge)
  66.     {
  67.         cPositionable::set_position(surface->edge + x - x1, y);
  68.         update_image_variables();
  69.         
  70.         went_off_screen_horiz = TRUE;
  71.     }
  72.     
  73.     else if (x2 > surface->w - surface->edge)
  74.     {
  75.         cPositionable::set_position(surface->w - surface->edge + x - x2, y);
  76.         update_image_variables();
  77.         
  78.         went_off_screen_horiz = TRUE;
  79.     }
  80.  
  81.     else
  82.     {
  83.         went_off_screen_horiz = FALSE;
  84.     }
  85. }
  86.  
  87. void cDisplayable::set_position(int _x, int _y)
  88. {
  89.     cXPositionable::set_position(_x, _y);
  90.     update_image_variables();
  91.     put_on_edge();
  92. }
  93.  
  94. void cDisplayable::set_position(fix _x, fix _y)
  95. {
  96.     cXPositionable::set_position(_x, _y);
  97.     update_image_variables();
  98.     put_on_edge();
  99. }
  100.  
  101. void cDisplayable::set_colormap(char *value)
  102. {
  103.     if (cmap != value)
  104.     {
  105.         cmap = value;
  106.  
  107.         force_dirty = TRUE;
  108.     }
  109. }
  110.  
  111. void cDisplayable::set_rotation_angle(fix angle)
  112.     angle = -angle;
  113.  
  114.     if (angle != rotation_angle)
  115.     {
  116.         rotation_angle = angle;
  117.  
  118.         force_dirty = TRUE;
  119.     }
  120. }
  121.  
  122. void cDisplayable::set_scale(fix _scale)
  123. {
  124.     ASSERT(_scale != (fix)0);
  125.  
  126.     if (scale != _scale)
  127.     {
  128.         scale = _scale;        
  129.         update_image_variables();
  130.         put_on_edge();
  131.  
  132.         force_dirty = TRUE;
  133.     }
  134. }
  135.  
  136. void cDisplayable::set_image(cImage *_image)
  137. {
  138.     // Check if there's change
  139.     
  140.     if (image == _image)
  141.         return;
  142.     
  143.     // Set image
  144.     
  145.     image = _image;
  146.  
  147.     if (image != 0)
  148.     {
  149.         bitmap = image->bmp;
  150.         image_wait = image->delay;        
  151.     }
  152.  
  153.     // Update variables that determine shape of image
  154.  
  155.     update_image_variables();
  156.     
  157.     // Make sure image is rewritten
  158.     
  159.     force_dirty = TRUE;
  160. }
  161.  
  162. void cDisplayable::kill_image()
  163. {
  164.     make_dirty();
  165.     
  166.     image = 0;
  167.     update_image_variables();
  168. }
  169.  
  170. void cDisplayable::write(int wx1, int wy1, int wx2, int wy2)
  171. {
  172.     // Check sanity
  173.     
  174.     if (image == 0)
  175.         return;
  176.     
  177.     // Get source and destination locations
  178.  
  179.     RECT sr;
  180.  
  181.     sr.left = x1 < wx1? wx1 - x1 : 0;
  182.     sr.right = wx2 < x2? wx2 - x1 + 1 : (int)(scale * bitmap->w);
  183.     sr.top = y1 > wy1? y1 - wy1 : 0;
  184.     sr.bottom = wy2 > y2? y1 - wy2 + 1 : (int)(scale * bitmap->h);
  185.     
  186.     RECT tr;
  187.  
  188.     tr.left = surface->x_screen(x1 > wx1? x1 : wx1); 
  189.     tr.right = tr.left + sr.right - sr.left;
  190.     tr.top = surface->y_screen(y1 < wy1? y1 : wy1);
  191.     tr.bottom = tr.top + sr.bottom - sr.top;
  192.  
  193.     // Get the colormap
  194.  
  195.     char *cm = 0;
  196.  
  197.     if (image->cmap != 0)
  198.         cm = image->cmap;
  199.     else if (cmap != 0)
  200.         cm = cmap;
  201.  
  202.     // Blit
  203.  
  204.     if (rotation_angle != (fix)0 || scale != (fix)1)
  205.     {    
  206.         int mx = surface->x_screen((x1 + x2) / 2),
  207.             my = surface->y_screen((y1 + y2) / 2);
  208.         
  209.         if (cm == 0)
  210.         {
  211.             switch(pixelformat.dwRGBBitCount)
  212.             {
  213.             case 8:
  214.                 rotated_blit(surface->dds, &tr, bitmap->dds, mx, my, rotation_angle, scale);
  215.                 break;
  216.  
  217.             case 16:
  218.                 rotated_blit16(surface->dds, &tr, bitmap->dds, mx, my, rotation_angle, scale);
  219.                 break;
  220.  
  221.             case 24:
  222.                 rotated_blit24(surface->dds, &tr, bitmap->dds, mx, my, rotation_angle, scale);
  223.                 break;
  224.  
  225.             case 32:
  226.                 rotated_blit32(surface->dds, &tr, bitmap->dds, mx, my, rotation_angle, scale);
  227.                 break;
  228.             }
  229.         }
  230.         else
  231.         {
  232.             switch(pixelformat.dwRGBBitCount)
  233.             {
  234.             case 8:
  235.                 if (inawin)
  236.                     rotated_blit(surface->dds, &tr, bitmap->dds, mx, my, rotation_angle, scale);
  237.                 else
  238.                     rotated_colormapped_blit(surface->dds, &tr, bitmap->dds, mx, my, rotation_angle, scale, cm);
  239.                 break;
  240.  
  241.             case 16:
  242.                 rotated_blit16(surface->dds, &tr, bitmap->dds, mx, my, rotation_angle, scale);
  243.                 break;
  244.  
  245.             case 24:
  246.                 rotated_blit24(surface->dds, &tr, bitmap->dds, mx, my, rotation_angle, scale);
  247.                 break;
  248.  
  249.             case 32:
  250.                 rotated_blit32(surface->dds, &tr, bitmap->dds, mx, my, rotation_angle, scale);
  251.                 break;            
  252.             }
  253.         }
  254.     }
  255.     else
  256.     {        
  257.         if (cm != 0 && !inawin)
  258.         {
  259.             colormapped_blit(surface->dds, &tr, bitmap->dds, &sr, cm);                        
  260.         }
  261.         else
  262.         {
  263.             LPDIRECTDRAWSURFACE4 best = bitmap->bestptr(surface);
  264.             while (!draw_ok(surface->dds->BltFast(tr.left, tr.top, best, &sr, DDBLTFAST_SRCCOLORKEY | DDBLTFAST_WAIT)));
  265.         }        
  266.     }
  267. }
  268.  
  269. void cDisplayable::write_gravity()
  270. {
  271.     // Check sanity
  272.  
  273.     if (image == 0 || image->gmap == 0)
  274.         return;
  275.  
  276.     // Write gravity
  277.  
  278.     RECT r;
  279.     
  280.     r.left = GAME_X;
  281.     r.right = GAME_X + GAME_DX;
  282.     r.top = 0;
  283.     r.bottom = GAME_DY;
  284.  
  285.     gravity_blit(backbuffer, &r, x - image->gmap[0] / 2, surface->start + surface->h - y - image->gmap[1] / 2, image->gmap);
  286. }